package avicit.bdp.dgs.mdm.service;

import avicit.bdp.common.base.BaseService;
import avicit.bdp.common.service.service.CommonTypeService;
import avicit.bdp.common.utils.BdpLogUtil;
import avicit.bdp.common.utils.CheckParaUtils;
import avicit.bdp.common.utils.enums.CommonTypeEnums;
import avicit.bdp.core.constant.Constants;
import avicit.bdp.dgs.mdm.dao.MdmRuleConfigDao;
import avicit.bdp.dgs.mdm.dto.MdmRuleConfigDTO;
import avicit.bdp.dgs.mdm.utils.enums.MdmCodeTypeEnum;
import avicit.platform6.api.system.ConvertColumnClient;
import avicit.platform6.api.system.impl.SystemConstant;
import avicit.platform6.commons.utils.BusinessUtil;
import avicit.platform6.commons.utils.ComUtil;
import avicit.platform6.core.exception.BusinessException;
import avicit.platform6.core.rest.msg.QueryRespBean;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.annotation.Resource;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * 主数据编码配置服务层
 *
 * @author mayi
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class MdmRuleConfigService extends BaseService<MdmRuleConfigDao, MdmRuleConfigDTO> {

  private static final Logger logger = LoggerFactory.getLogger(MdmRuleConfigService.class);

  @Resource private MdmRuleConfigDao mdmRuleConfigDao;
  @Resource private CommonTypeService commonTypeService;
  @Resource private ConvertColumnClient convertColumnClient;

  public QueryRespBean<MdmRuleConfigDTO> getPageList(
      String typeId,
      String modelId,
      String type,
      String keyWords,
      Integer pageNo,
      Integer pageSize)
      throws Exception {
    
    if (StringUtils.isEmpty(type)) {
      throw new BusinessException("码段类型不能为空");
    }

    List<String> typeIdList = new ArrayList<>();
    if (StringUtils.isNotEmpty(typeId)) {
      commonTypeService.typeIdConvert(
          typeId, typeIdList, CommonTypeEnums.DGS_STANDARD_DATA_ELEMENT_TYPE);
    }

    QueryRespBean<MdmRuleConfigDTO> queryRespBean = new QueryRespBean<>();
    PageHelper.startPage(pageNo, pageSize);
    Page<MdmRuleConfigDTO> page =
        mdmRuleConfigDao.getPageList(typeIdList, modelId, type, keyWords);
    try {
      valueConvert(page);
    } catch (Exception e) {
      e.printStackTrace();
    }
    queryRespBean.setResult(page);
    return queryRespBean;
  }

  private void valueConvert(Page<MdmRuleConfigDTO> page) {
    // 循环组装请求数据
    Map<String, Set<String>> convertFormData = new HashMap<>(16);
    for (MdmRuleConfigDTO dto : page) {
      BusinessUtil.createConvertSet(convertFormData, SystemConstant.USER, dto.getCreatedBy());
      if (StringUtils.isNotBlank(dto.getType())) {
        dto.setTypeName(MdmCodeTypeEnum.getDescByCode(dto.getType()));
      }
    }
    if (convertFormData.size() > 0) {
      // 获取请求结果
      Map<String, Map<String, String>> convertResultData =
          convertColumnClient.replace(convertFormData);
      // 循环设置Alias或Name的值
      for (MdmRuleConfigDTO dto : page) {
        dto.setCreatedBy(
            BusinessUtil.convertFormat(convertResultData, SystemConstant.USER, dto.getCreatedBy()));
      }
    }
  }

  public String save(MdmRuleConfigDTO dto) {

    valid(dto);

    checkNameUnique(dto);

    checkCodeUnique(dto);

    dto.setId(ComUtil.getId());

    this.insert(dto);
    log4Insert(dto);

    return dto.getId();
  }

  public void update(MdmRuleConfigDTO dataElementDto) {

    valid(dataElementDto);

    MdmRuleConfigDTO oldDto = this.selectByPrimaryKey(dataElementDto.getId());
    CheckParaUtils.checkDbObjectValidity(
        oldDto, logger, String.format("没有查到数据，请确保id:%s的数据是否存在", dataElementDto.getId()));

    // 校验名称唯一性
    if (!dataElementDto.getName().equals(oldDto.getName())) {
      checkNameUnique(dataElementDto);
    }

    // 校验编码唯一性
    if (!dataElementDto.getCode().equals(oldDto.getCode())) {
      checkCodeUnique(dataElementDto);
    }

    this.updateByPrimaryKey(dataElementDto);
    BdpLogUtil.log4Update(dataElementDto, oldDto);
  }

  private void valid(MdmRuleConfigDTO dto) {
    CheckParaUtils.checkObjectValidity(dto.getCode(), logger, "码段编码不能为空");
    CheckParaUtils.checkStringValidity(dto.getName(), logger, "码段名称不能为空");
  }

  public Boolean batchDelete(String ids) {
    CheckParaUtils.checkStringValidity(ids, logger, "没有传入待删除的ID");
    String[] idArr = ids.split(Constants.COMMA);
    for (String id : idArr) {
      MdmRuleConfigDTO dataElementDto = this.selectByPrimaryKey(id);
      CheckParaUtils.checkDbObjectValidity(
          dataElementDto, logger, String.format("没有查到数据，请确保id:%s的数据是否存在", id));

      this.mapper.deleteByPrimaryKey(id);

      // 记录日志
      BdpLogUtil.log4Delete(dataElementDto);
    }
    return true;
  }

  public MdmRuleConfigDTO queryById(String id) {
    MdmRuleConfigDTO dataElementDto = this.selectByPrimaryKey(id);
    CheckParaUtils.checkDbObjectValidity(
        dataElementDto, logger, String.format("没有查到数据，请确保id:%s的数据是否存在", id));
    return dataElementDto;
  }

  public List<MdmRuleConfigDTO> listRule() {
    return this.selectListAll();
  }

  /**
   * 校验码段名称唯一性
   *
   * @param dto 检测对象
   */
  private void checkNameUnique(MdmRuleConfigDTO dto) {
    if (dto != null) {
      if (StringUtils.isEmpty(dto.getName())) {
        throw new BusinessException("码段名称不能为空");
      }

      MdmRuleConfigDTO paramName = new MdmRuleConfigDTO();
      paramName.setName(dto.getName());
      if (this.selectCount(paramName) > 0) {
        throw new BusinessException("码段名称[" + dto.getName() + "]已存在");
      }
    }
  }

  /**
   * 校验码段编码唯一性
   *
   * @param dto 检测对象
   */
  private void checkCodeUnique(MdmRuleConfigDTO dto) {
    if (dto != null) {
      if (StringUtils.isEmpty(dto.getCode())) {
        throw new BusinessException("码段编码不能为空");
      }

      MdmRuleConfigDTO paramCode = new MdmRuleConfigDTO();
      paramCode.setCode(dto.getCode());
      if (this.selectCount(paramCode) > 0) {
        throw new BusinessException("码段编码[" + dto.getCode() + "]已存在");
      }
    }
  }
}
